<template>
  <div class="app-container realtime">
    <div class="buttom-icon">
      <div class="state">
        <div class="legend">
          <span v-for="(value, name, i) in stateLegend" :key="i">
            <i :style="{ background: value.bgCol }"></i>{{ value.title }}
          </span>
        </div>
      </div>
      <el-button
        class="el-icon-full-screen"
        size="mini"
        @click="openFullScreen"
      ></el-button>
      <el-button
        class="el-icon-plus"
        size="mini"
        @click="handleBig"
      ></el-button>
      <el-button
        class="el-icon-minus"
        size="mini"
        @click="handleSemall"
      ></el-button>
      <el-button
        class="el-icon-s-home"
        size="mini"
        @click="handleHome"
      ></el-button>
    </div>
    <div class="compact-box-tree-page">
      <div
        class="compact-box-tree-canvas"
        :style="{ height: boxHeight }"
        id="dag-canvas"
      ></div>
    </div>
  </div>
</template>

<script>
import Node from "./node.js";
import { TreeCanvas, Tips } from "butterfly-dag";
import $ from "jquery";
import "butterfly-dag/dist/index.css";
let vueRoot = null;
import screenfull from "screenfull"; //全屏的组件
export default {
  name: "Dag",
  props: {
    mockData: {
      type: Object,
      default: () => {},
      required: true,
    },
  },
  data() {
    return {
      boxHeight: document.body.clientHeight - 125 + "px",
      mainStreamId: "",
      zoom: 1,
      dialogVisible: false, //弹窗开关
      isFullscreen: true, //全屏
      // 色卡
      stateLegend: {
        "-1": {
          title: "暂未提交",
          bgCol: "#666666",
        },
        0: {
          state: 0,
          title: "错误状态",
          bgCol: "#7a8d93",
        },
        1: {
          state: 1,
          title: "正在运行",
          bgCol: "#01a0c7",
        },
        2: {
          state: 2,
          title: "准备暂停",
          bgCol: "#e1e143",
        },
        3: {
          state: 3,
          title: "暂停状态",
          bgCol: "#ffcc01",
        },
        4: {
          state: 4,
          title: "准备停止",
          bgCol: "#fa686b",
        },
        5: {
          state: 5,
          title: "停止状态",
          bgCol: "#fe6625",
        },
        6: {
          state: 6,
          title: "失败状态",
          bgCol: "#fe0000",
        },
        7: {
          state: 7,
          title: "成功状态",
          bgCol: "#99cf17",
        },
        8: {
          state: 8,
          title: "未知错误",
          bgCol: "#666666",
        },
        9: {
          state: 9,
          title: "忽略状态",
          bgCol: "#98175c",
        },
        10: {
          state: 10,
          title: "已被杀死",
          bgCol: "#571f1a",
        },
        11: {
          state: 11,
          title: "准备运行",
          bgCol: "#10d451",
        },
        20: {
          state: 20,
          title: "前置失败",
          bgCol: "#c76060",
        },
      },
    };
  },
  watch: {
    mockData: {
      // 监视mockData,如果有数据变化进行渲染
      handler(newData, oldData) {
        this.draw();
      },
      deep: true,
    },
  },
  created() {
    vueRoot = this;
  },
  mounted() {
    this.test();
  },
  methods: {
    reset() {},
    // dag全屏按钮-展示dialog
    openFullScreen() {
      screenfull.toggle(); //全屏的方法
    },
    // dag全屏按钮-展示dialog
    closeFullScreen() {
      screenfull.toggle();
    },
    //画布缩小
    handleSemall() {
      if (this.zoom == 1) {
        let num = parseFloat(this.zoom - 0.2).toFixed(2) - 0;
        this.zoom = num;
        vueRoot.canvas.zoom(num);
      } else {
        let num = parseFloat(this.zoom - 0.1).toFixed(2) - 0;
        this.zoom = num;
        vueRoot.canvas.zoom(num);
      }
    },
    //画布放大
    handleBig() {
      let num = parseFloat(this.zoom + 0.1).toFixed(2) - 0;
      this.zoom = num;
      vueRoot.canvas.zoom(num);
    },
    handleHome() {
      this.zoom = 1;
      vueRoot.canvas.focusCenterWithAnimate();
    },
    test() {
      let root = document.getElementById("dag-canvas");
      this.canvas = new TreeCanvas({
        root: root,
        disLinkable: true, // 可删除连线
        linkable: true, // 可连线
        draggable: true, // 可拖动
        zoomable: true, // 可放大
        moveable: true, // 可平移
        theme: {
          edge: {
            shapeType: "BrokenLine",
            arrow: true,
            arrowPosition: 0.6,
          },
        },
        layout: {
          type: "compactBox",
          options: {
            direction: "TB",
            controlPoints: false,
            getHeight(d) {
              return 60;
            },
            getWidth(d) {
              return 220;
            },
            getHGap(d) {
              return 20;
            },
            getVGap(d) {
              return 80;
            },
          },
        },
      });
      vueRoot.canvas.setMinimap(true, {
        nodeColor: "#01B9F5",
      }); //右下角的小地图
      this.draw();
      console.log("初始化test-draw");
    },
    // 渲染
    draw() {
      //给所有的节点添加一个Class = Node属性
      let children = this.addAttribute(vueRoot.mockData.nodes.children || []);
      // 初始化的Root在此创建 将children进行赋值到Root的children
      let mockData = {
        nodes: {
          isRoot: true,
          id: "root_conistudy_jiedian",
          title: "开始",
          content: "00",
          Class: Node,
          endpoints: [
            {
              id: "root_conistudy_jiedian",
              orientation: [0, 1],
              pos: [0.5, 0.5],
            },
          ],
          children: [...new Set(children)],
        },
        edges: [...vueRoot.mockData.edges],
      };
      console.log("绘制-redraw");
      vueRoot.canvas.redraw(mockData, {}, (data) => {
        let nodes = data.nodes;
        //将所有的节点进行遍历,如果节点有名称为其他并有children
        nodes.forEach((item) => {
          /*
           如果mainStreamId主流程不一样&&title不是root或者其他 状态不是00
          将显示当前点击节点的主流程其他的主流程将被隐藏
          */
          if (
            vueRoot.mainStreamId &&
            item.options.options.title !== "开始" &&
            item.options.options.title !== "其他" &&
            item.options.options.content !== "00" &&
            vueRoot.mainStreamId !== item.options.options.mainStreamId
          ) {
            item.collapse(); //节点收起
          }
          //如果有开始时间显示开始时间tips  反之==>显示节点的title
          if (item.options.options.startTime) {
            Tips.createTip({
              targetDom: item.dom.childNodes[0],
              genTipDom: () => {
                return $(`<div >
                  <span>${item.options.options.title}</span><br/>
                  <span>开始时间:${
                    item.options.options.startTime
                      ? item.options.options.startTime
                      : "暂无数据"
                  }</span><br/>
                  <span>结束时间:${
                    item.options.options.endTime
                      ? item.options.options.endTime
                      : "暂无数据"
                  }</span><br/>
                  <span>运行时长:${
                    item.options.options.runTime
                      ? item.options.options.runTime
                      : "暂无数据"
                  }${item.options.options.runTime ? "分钟" : ""}</span>
                </div>`).css("text-align", "left")[0];
              },
              placement: "right",
            });
          } else {
            Tips.createTip({
              targetDom: item.dom.childNodes[0],
              genTipDom: () => {
                return $(`<div >
                  <span>${item.options.options.title}</span>
                </div>`).css("text-align", "left")[0];
              },
              placement: "top",
            });
          }
        });
        // //如果节点的长度大于10 将进行偏移
        // if (vueRoot.mockData.nodes.children.length > 10) {
        //   vueRoot.canvas.setOrigin([0, 80]); //手动设置 画布缩放的中心点,一般跟随着鼠标的位置
        // } else {
        //   //节点长度不大于10 居中进行显示
        //   vueRoot.canvas.focusCenterWithAnimate();
        //   vueRoot.canvas.setOrigin([0, 20]); //手动设置 画布缩放的中心点,一般跟随着鼠标的位置
        // }
        vueRoot.canvas.focusCenterWithAnimate();

        // vueRoot.canvas.zoom(1.28); //进行放大1.28倍
        // vueRoot.canvas.setOrigin([-180, -170]); //手动设置 画布缩放的中心点,一般跟随着鼠标的位置
        // vueRoot.canvas.on("canvas.zoom", (data) => {
        //   //data 数据
        //   console.log(data);
        // });
      });
      console.log("设置-setMoveable");
      vueRoot.canvas.setMoveable(true);
    },
    //根据id进行查找到响应节点并删除childern 和线
    remove(id) {
      console.log(id);
      this.removeObjById(vueRoot.mockData.nodes.children, id);
      this.removeEdges(vueRoot.mockData.edges, id);
    },
    //点击名称
    titleClick(state, id, item, type, itemstate) {
      if (type === "title") {
        //如果有状态并且状态不是00 因为00的根节点
        // if (state !== "00" && item.options.title !== "其他") {
        if (state !== "00") {
          vueRoot.mainStreamId = item.options.mainStreamId;
          console.log(item, state, "我是点击节点状态");
          vueRoot.$emit("loadMore", id, item);
        }
      }
    },
    //点击节点状态
    stateClick(item, state) {
      vueRoot.$parent.getTaskRunInfosDetail(item, state);
    },
    //右键单击
    rightClick(e, item, isShowMenu) {
      if (isShowMenu) {
        vueRoot.$parent.dagRightClick(e, item, isShowMenu);
      } else {
        vueRoot.$parent.isShowRightMenu = isShowMenu;
      }
    },
    // tree结构递归添加属性
    addAttribute(data) {
      for (var i = 0; i < data.length; i++) {
        data[i].Class = Node;
        if (data[i].children && data[i].children.length > 0) {
          this.addAttribute(data[i].children);
        }
      }
      return data;
    },
    //查询id所在的节点并删除
    removeObjById(list, id) {
      list.map((item, index) => {
        if (item.id === id) {
          item.children = [];
          return item;
        } else {
          if (item.children) {
            let obj = this.removeObjById(item.children, id);
            if (obj) return obj;
          }
        }
      });
    },
    //查询id的线进行删除
    removeEdges(list, id) {
      vueRoot.mockData.edges = [...list].filter((item) => {
        return item.source !== id;
      });
      // console.log(vueRoot.mockData.edges);
    },
  },
};
</script>

<style scoped lang="scss">
.realtime {
  width: 100%;
  height: 100%;
  background: #fff;
  position: relative;

  .compact-box-tree-page {
    width: 100%;
    height: 100%;
    .compact-box-tree-canvas {
      width: 100%;
      height: 100%;
    }
  }
}
.buttom-icon {
  margin: 10px 50px 0 0;
  display: flex;
  justify-content: right;
  .state {
    display: flex;
    justify-content: flex-end;
  }
  .legend {
    display: flex;
    margin-top: 6px;
    span {
      font-size: 12px;
      color: #999999;
      margin: 10px 14px;
      display: flex;
      align-items: center;
      i {
        width: 20px;
        height: 12px;
        display: block;
        background: #ccc;
        border-radius: 3px;
        margin-right: 5px;
      }
    }
  }
}
</style>
